package info.sean.util.common;



import info.sean.util.common.bizk.StringUtils;

import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by wenjing on 2016-3-8.
 */
public class StringUtil extends org.apache.commons.lang3.StringUtils {

    public static final String EMPTY = "";
    public static final String DEFAULT_CHARSET_NAME = "UTF-8";
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    public static final String DEFAULT_TIME_FORMAT = "yyyyMMddHHmmss";
    public static final String DEFAULT_TIME_FORMAT_12 = "yyMMddHHmmss";
    public static final String DATE_FORMAT_YYYYMMDD = "yyyyMMdd";
    public static final String DEFAULT_DATE_FORMAT_1 = "yyyy-MM-dd HH:mm:ss";

    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); //NOSONAR

        }
        return d;
    }

    /**
     * 取得第一个出现的分隔子串之后的子串。
     * <p>
     * <p>
     * 如果字符串为<code>null</code>，则返回<code>null</code>。 如果分隔子串为<code>null</code> 或未找到该子串，则返回原字符串。
     * <p>
     * <pre>
     * StringUtil.substringAfter(null, *)      = null
     * StringUtil.substringAfter("", *)        = ""
     * StringUtil.substringAfter(*, null)      = ""
     * StringUtil.substringAfter("abc", "a")   = "bc"
     * StringUtil.substringAfter("abcba", "b") = "cba"
     * StringUtil.substringAfter("abc", "c")   = ""
     * StringUtil.substringAfter("abc", "d")   = ""
     * StringUtil.substringAfter("abc", "")    = "abc"
     * </pre>
     * <p>
     * </p>
     *
     * @param str       字符串
     * @param separator 要搜索的分隔子串
     * @return 子串，如果原始串为<code>null</code>，则返回<code>null</code>
     */
    public static String substringAfter(String str, String separator) {
        if ((str == null) || (str.length() == 0)) {
            return str;
        }

        if (separator == null) {
            return EMPTY;
        }

        int pos = str.indexOf(separator);

        if (pos == -1) {
            return EMPTY;
        }

        return str.substring(pos + separator.length());
    }

    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    public static String replaceBlank(String str) {
        String dest = "";
        if (str != null) {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }

    public static String[] splitStr2Array(String source, String spliter) {
        String regex = spliter;
        if ((regex.equals("?")) || (regex.equals("*")) || (regex.equals(")")) || (regex.equals("(")) || (regex.equals("{")) || (regex.equals("$"))
                || (regex.equals("+")) || (regex.equals(".")) || (regex.equals("|"))) {
            regex = "[" + regex + "]";
        }
        return source.split(regex);
    }

    public static String byte2Hex(byte[] srcBytes) {
        StringBuilder hexRetSB = new StringBuilder();
        for (byte b : srcBytes) {
            String hexString = Integer.toHexString(0xFF & b);
            hexRetSB.append(hexString.length() == 1 ? Integer.valueOf(0) : "").append(hexString);
        }
        return hexRetSB.toString();
    }

    public static byte[] hex2Bytes(String source) {
        byte[] sourceBytes = new byte[source.length() / 2];
        for (int i = 0; i < sourceBytes.length; i++) {
            sourceBytes[i] = ((byte) Integer.parseInt(source.substring(i * 2, i * 2 + 2), 16));
        }
        return sourceBytes;
    }

    public static String truncateString(String src, int length) {

        if (StringUtils.hasText(src) && src.length() > length && length > 10) {
            src = src.substring(0, length - 4) + "...";
        }
        return src;
    }

    // 将Unicode码转换为中文
    public static String unicodeTozhCN(String unicode) {

        if (!StringUtils.hasText(unicode)) {
            return unicode;
        }

        StringBuffer gbk = new StringBuffer();
        String hex[] = unicode.split("\\\\u");
        for (int i = 1; i < hex.length; i++) { // 注意要从 1 开始，而不是从0开始。第一个是空。
            int data = Integer.parseInt(hex[i], 16); // 将16进制数转换为 10进制的数据。
            gbk.append((char) data); // 强制转换为char类型就是我们的中文字符了。
        }
        return gbk.toString();
    }

    // 将字符串转换为Unicode码
    public static String toUnicode(String zhStr) {

        if (!StringUtils.hasText(zhStr)) {
            return zhStr;
        }

        StringBuilder unicode = new StringBuilder();
        for (int i = 0; i < zhStr.length(); i++) {
            char c = zhStr.charAt(i);
            unicode.append("\\u");
            unicode.append(Integer.toHexString(c));
        }
        return unicode.toString();
    }

    public static byte[] getContentBytes(String content, String charset) {
        if (charset == null || "".equals(charset)) {
            try {
                return content.getBytes(DEFAULT_CHARSET_NAME);
            } catch (UnsupportedEncodingException e) {
                throw new IllegalArgumentException("", e);
            }
        }

        try {
            return content.getBytes(charset);
        } catch (UnsupportedEncodingException ex) {
            throw new IllegalArgumentException("Not support:" + charset, ex);
        }
    }

    public static String nvlStr(Object contend) {
        return contend != null ? (contend.toString()) : "";
    }

    public static void append(StringBuilder sb, Object o) {
        if (o == null) {
            return;
        }
        sb.append(o.toString());
    }

    public static String toLowerCase(String str) {
        if (str == null) {
            return null;
        }

        return str.toLowerCase();
    }

    public static String trim(Object obj, char str2) {
        if (obj == null) {
            return "";
        }
        String str1 = obj.toString();
        int len = str1.length();
        int st = 0;
        char[] val = str1.toCharArray();
        while ((st < len) && (val[st] <= str2)) {
            st++;
        }
        while ((st < len) && (val[len - 1] <= str2)) {
            len--;
        }
        return (String) (((st > 0) || (len < str1.length())) ? substring(st, len, str1) : str1);
    }

    public static String substring(int beginIndex, int endIndex, String value) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.length()) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        int subLen = endIndex - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return (String) (((beginIndex == 0) && (endIndex == value.length())) ? value : new String(value.toCharArray(), beginIndex, subLen));
    }


    /**
     * 将字符串中的{yyyymmdd}占位符替换成真实日期
     * 例如:
     * 输入: "2018-08-06 22:03:00", "some_folder\{yyyy_MM}\some_file_{yyyyMMdd}.csv"
     * 输出	: "some_folder\2018_08\some_file_20180806.csv"
     *
     * @param date
     * @param fileNameRule
     * @return
     */
    public static String replaceDateInFileName(Date date, String fileNameRule) {

        String patt = "\\{(\\w+)\\}";
        Pattern pattern = Pattern.compile(patt);
        Matcher matcher = pattern.matcher(fileNameRule);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            String timeFormat = matcher.group(1);
            String timeStr = new SimpleDateFormat(timeFormat).format(date);
            matcher.appendReplacement(sb, timeStr);
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * @param dateString
     * @param format
     * @return
     * @brief 日期字符串转成Date
     * @occurs required
     */
    public static Date string2Date(String dateString, String format) {
        if (isBlank(dateString)) {
            return null;
        }

        if (isEmpty(format)) {
            format = DEFAULT_DATE_FORMAT;
        }

        SimpleDateFormat formatter = new SimpleDateFormat(format, Locale.US);

        try {
            return formatter.parse(dateString);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * @param date
     * @param format
     * @return
     * @brief Date转成日期字符串
     * @occurs required
     */
    public static String date2String(Date date, String format) {
        if (date == null) {
            return null;
        }

        if (isEmpty(format)) {
            format = DEFAULT_DATE_FORMAT;
        }

        SimpleDateFormat formatter = new SimpleDateFormat(format, Locale.US);
        return formatter.format(date);
    }

    /**
     * 清理空白字符
     *
     * @param str 被清理的字符串
     * @return 清理后的字符串
     */
    public static String cleanBlank(CharSequence str) {
        if (str == null) {
            return null;
        }

        int len = str.length();
        final StringBuilder sb = new StringBuilder(len);
        char c;
        for (int i = 0; i < len; i++) {
            c = str.charAt(i);
            if (false == isBlankChar(c)) {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 是否空白符<br>
     * 空白符包括空格、制表符、全角空格和不间断空格<br>
     */
    public static boolean isBlankChar(char c) {
        return isBlankChar((int) c);
    }

    /**
     * 是否空白符<br>
     * 空白符包括空格、制表符、全角空格和不间断空格<br>
     */
    public static boolean isBlankChar(int c) {
        return Character.isWhitespace(c) || Character.isSpaceChar(c) || c == '\ufeff' || c == '\u202a';
    }
}
